package com.njlime.sys.security;

import com.alibaba.fastjson.JSONObject;
import com.njlime.core.exception.ExceptionState;
import com.njlime.core.utils.StringUtil;
import com.njlime.sys.entities.Menu;
import com.njlime.sys.security.util.UserUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

public class RightCheckFilter extends AccessControlFilter {

    private String errorUrl;

    public String getErrorUrl() {
        return errorUrl;
    }

    public void setErrorUrl(String errorUrl) {
        this.errorUrl = errorUrl;
    }

    Logger logger = Logger.getLogger(RightCheckFilter.class);

    /**
     * 表示是否允许访问 ，如果允许访问返回true，否则false；
     *
     * @param servletRequest
     * @param servletResponse
     * @param o 表示写在拦截器中括号里面的字符串 mappedValue 就是 [urls] 配置中拦截器参数部分
     * @return
     * @throws Exception
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception {
        Subject subject = getSubject(servletRequest, servletResponse);
        String url = getPathWithinApplication(servletRequest);


        boolean isPermitted = subject.isPermitted(url);
        logger.info("当前用户正在访问的 url => " + url+" "+isPermitted);
        if(isPermitted){
            //如果权限验证通过，则获取用户拥有的当前页面的所有权限
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            List<Menu> menuList = UserUtils.getMenuList();
            String parent_ids = "";
            String permission = "";
            for(Menu menu : menuList){
                if(url.equals(menu.getUrl())){
                    parent_ids = menu.getParent_ids();
                    break;
                }
            }
            for(Menu menu : menuList){
                if(parent_ids.equals(menu.getParent_ids()) && !StringUtil.isEmpty(menu.getPermission()) && !permission.contains(menu.getPermission() + ",")){
                    permission += menu.getPermission() + ",";
                }
            }
            request.setAttribute("permission",StringUtil.isEmpty(permission) ? permission : permission.substring(0,permission.length()-1));
        }
        return isPermitted;
    }


    /**
     * onAccessDenied：表示当访问拒绝时是否已经处理了；如果返回 true 表示需要继续处理；如果返回 false 表示该拦截器实例已经处理了，将直接返回即可。
     *
     * @param servletRequest
     * @param servletResponse
     * @return
     * @throws Exception
     */
    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        logger.debug("当 isAccessAllowed 返回 false 的时候，才会执行 method onAccessDenied ");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //response.sendRedirect(request.getContextPath() + this.errorUrl);
        if (request.getHeader("x-requested-with") != null && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("resCode", ExceptionState.PERMISSION_EXCEPTION);
            jsonObject.put("message","没有此操作的权限");
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/html; charset=utf-8");
            PrintWriter out = null;
            try {
                out = response.getWriter();
                out.append(jsonObject.toJSONString());
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (out != null) {
                    out.close();
                }
            }
        }else{
            request.setAttribute("resCode", ExceptionState.PERMISSION_EXCEPTION);
            request.setAttribute("message", "没有此操作的权限");
            request.getRequestDispatcher("/exceptionView").forward(request, response);
        }
        // 返回 false 表示已经处理，例如页面跳转啥的，表示不在走以下的拦截器了（如果还有配置的话）
        return false;
    }
}